/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_Studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#pragma once

#include "物理/物理.h"

#include "../节点.h"
#include <物体/物体.h>
#include <面/面.h>





class API_EXPORT C_物理碰撞节点 : public C_节点基类 {

public:
	C_物理碰撞节点(S_设备环境& ctx);

	E_物理几何体类型	m_物理体类型;

	bool				f_update();

};
C_节点基类* f_node_创建物理碰撞节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载物理碰撞节点(S_设备环境& ctx, FILE* f);
void		f_node_保存物理碰撞节点(C_节点基类* n, FILE* f);



class API_EXPORT C_物理几何体节点 : public C_节点基类 {
	//S_物体* m_物体;
	std::vector<S_物体*>	m_物体;
	std::vector<S_物体*>	m_链接可视物体;
public:
	C_物理几何体节点(S_设备环境& ctx);
	~C_物理几何体节点();

	S_Props	m_物理引擎类型;
	S_Props	m_几何体类型;

	S_Props		m_重量;
	S_Props		m_密度;
	S_Props		m_弹性;
	S_Props		m_阻尼;
	S_Props		m_边缘距离;
	S_Props		m_摩擦;
	S_Props		m_旋转惯性;

	S_Props		m_接触参考;
	S_Props		m_接触实施;
	S_Props		m_接触混合;

	S_Props		m_碰撞位掩码;
	S_Props		m_接触的频率;
	S_Props		m_接触自由度;

	void	f_更新虚拟体绘制属性(S_物体* ob, E_物理几何体类型 几何体类型, const vec3& size, S_Mesh* me = nullptr);
	void	f_创建操作虚拟体(S_物体** 几何体, S_物体** 链接轴);
	bool	f_update();

	S_物体* f_虚拟体();
	void	f_删除();
	void	f_回收();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);

	void	f_Copy(const C_节点基类* node);
};

C_节点基类* f_node_创建物理几何体节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载物理几何体节点(S_设备环境& ctx, FILE* f);
void		f_node_保存物理几何体节点(C_节点基类* n, FILE* f);




class API_EXPORT C_物理体节点 : public C_节点基类 {
	S_物体*		m_数据可视物体;
	uint8		m_是否完成计算;

	//std::vector<S_物体*>	m_物体;
	
public:
	C_物理体节点(S_设备环境& ctx);
	~C_物理体节点();
	
	S_Props		m_物理引擎类型;
	S_Props		m_物理体类型;
	S_Props		m_粒子最大数;
	S_Props		m_填充方式;
	S_Props		m_是否多线程;

	

	S_Props		m_链接类型;
	S_Props		m_链接轴向;
	S_Props		m_限定范围;
	S_Props		m_关节范围;
	S_Props		m_关节阻尼;
	S_Props		m_关节刚度;
	S_Props		m_关节摩擦;

	bool		f_update();
	void		f_异步解算();

	void		f_读取(FILE* f);
	void		f_写入(FILE* f);

	S_物体*		f_虚拟体();
	void		f_删除();
	void		f_回收();

	void		f_Copy(const C_节点基类* node);
};

C_节点基类* f_node_创建物理体节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载物理体节点(S_设备环境& ctx, FILE* f);
void		f_node_保存物理体节点(C_节点基类* n, FILE* f);





//class C_物理体链接节点 : public C_节点基类 {
//	S_物体* m_数据可视物体;
//	uint8		m_是否完成计算;
//public:
//	C_物理体链接节点(S_设备环境& ctx);
//	~C_物理体链接节点();
//
//	S_Props		m_链接类型;
//
//	bool		f_update();
//
//	void		f_读取(FILE* f);
//	void		f_写入(FILE* f);
//
//	S_物体* f_get虚拟体();
//
//};
//
//C_节点基类* f_node_创建物理体链接节点(S_设备环境& ctx, C_节点树* 子节点树);
//C_节点基类* f_node_加载物理体链接节点(S_设备环境& ctx, FILE* f);
//void		f_node_保存物理体链接节点(C_节点基类* n, FILE* f);




class API_EXPORT C_物理体添加节点 : public C_节点基类 {
	
public:
	C_物理体添加节点(S_设备环境& ctx);

	bool		f_update();
	//void		f_读取(FILE* f);
	//void		f_写入(FILE* f);
	C_插座基类*	f_动态添加插座(E_插座方向 方向);
};

C_节点基类* f_node_加载物理体添加节点(S_设备环境& ctx, FILE* f);
void		f_node_保存物理体添加节点(C_节点基类* n, FILE* f);



class API_EXPORT C_取物理体节点 : public C_节点基类 {

public:
	C_取物理体节点(S_设备环境& ctx);
	~C_取物理体节点();

	S_Props	m_物理几何类型;
	bool	f_update();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_加载取物理体节点(S_设备环境& ctx, FILE* f);
void		f_node_保存取物理体节点(C_节点基类* n, FILE* f);



class API_EXPORT C_物理体绑定物体节点 : public C_节点基类 {

public:
	C_物理体绑定物体节点(S_设备环境& ctx);
	~C_物理体绑定物体节点();

	//S_Props		m_物理几何类型;
	E_物理几何体类型 几何类型;

	bool	f_update();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_加载物理体绑定物体节点(S_设备环境& ctx, FILE* f);
void		f_node_保存物理体绑定物体节点(C_节点基类* n, FILE* f);




class API_EXPORT C_物理引擎内部几何节点 : public C_节点基类 {
public:
	C_物理引擎内部几何节点(S_设备环境& ctx);
	~C_物理引擎内部几何节点();

	bool	f_update();

	void	f_读取(FILE* f);
	void	f_写入(FILE* f);
};

C_节点基类* f_node_加载物理引擎内部几何节点(S_设备环境& ctx, FILE* f);
void		f_node_保存物理引擎内部几何节点(C_节点基类* n, FILE* f);



class API_EXPORT C_粒子系统节点 : public C_节点基类 {
	S_物体* m_默认粒子系统;
	
public:
	C_粒子系统节点(S_设备环境& ctx);
	~C_粒子系统节点();

	S_物理体* m_物理体;

	S_Props		m_包含属性;

	S_Props		m_渲染类型;
	S_Props		m_系统名称;
	S_Props		m_粒子数量;
	S_Props		m_粒子寿命;
	S_Props		m_寿命随机比;
	S_Props		m_粒子大小;
	S_Props		m_随机大小;
	S_Props		m_随机大小区间;

	S_Props		m_坐标属性名称;
	S_Props		m_旋转属性名称;
	S_Props		m_速度属性名称;
	S_Props		m_大小属性名称;
	S_Props		m_寿命属性名称;
	S_Props		m_年龄属性名称;


	bool			f_update();
	void			f_读取(FILE* f);
	void			f_写入(FILE* f);
};

C_节点基类* f_node_创建粒子系统节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载粒子系统节点(S_设备环境& ctx, FILE* f);
void		f_node_保存粒子系统节点(C_节点基类* n, FILE* f);




class API_EXPORT C_发射节点 : public C_节点基类 {

public:
	C_发射节点(S_设备环境& ctx);
	~C_发射节点();

	S_Props		m_发射方式;
	S_Props		m_粒子系统;
	

	bool		f_update();
	void		f_异步解算();

	void		f_读取(FILE* f);
	void		f_写入(FILE* f);
};

C_节点基类* f_node_创建发射节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载发射节点(S_设备环境& ctx, FILE* f);
void		f_node_保存发射节点(C_节点基类* n, FILE* f);




class API_EXPORT C_力对象节点 : public C_节点基类 {

public:
	C_力对象节点(S_设备环境& ctx);
	~C_力对象节点();

	S_Props		m_力类型;
	S_Props		m_使用范围;

	S_Props		m_范围形状;
	S_Props		m_最小范围;
	S_Props		m_最大范围;

	S_Props		m_范围最小高度;
	S_Props		m_范围最大高度;


	bool		f_update();

	void		f_读取(FILE* f);
	void		f_写入(FILE* f);
};

C_节点基类* f_node_创建力对象节点(S_设备环境& ctx, C_节点树* 子节点树);
C_节点基类* f_node_加载力对象节点(S_设备环境& ctx, FILE* f);
void		f_node_保存力对象节点(C_节点基类* n, FILE* f);














